package com.qqt.csr.web.controller;

import com.qqt.csr.common.exception.StatusCode;
import com.qqt.csr.common.idempotent.Idempotent;
import com.qqt.csr.common.interceptor.auth.Authorize;
import com.qqt.csr.common.interceptor.auth.IgnoreAuthorize;
import com.qqt.csr.common.log.Log;
import com.qqt.csr.common.operalog.BusinessType;
import com.qqt.csr.common.operalog.LogLevel;
import com.qqt.csr.common.operalog.OperationLog;
import com.qqt.csr.common.session.SessionContextHolder;
import com.qqt.csr.common.utils.RedissonLockUtil;
import com.qqt.csr.common.utils.ServiceAssert;
import com.qqt.csr.common.vo.req.PageRequest;
import com.qqt.csr.common.vo.resp.ObjectResponse;
import com.qqt.csr.common.vo.resp.PageResponse;
import com.qqt.csr.route.service.CsStatusService;
import com.qqt.csr.workbench.convert.SkillSetConfigAssembler;
import com.qqt.csr.workbench.entity.SkillSet;
import com.qqt.csr.workbench.entity.SkillSetConfig;
import com.qqt.csr.workbench.service.SkillSetConfigService;
import com.qqt.csr.workbench.service.SkillSetMemberService;
import com.qqt.csr.workbench.service.SkillSetService;
import com.qqt.csr.workbench.vo.req.*;
import com.qqt.csr.workbench.vo.resp.SkillSetConfigInfoRespVO;
import com.qqt.csr.workbench.vo.resp.SkillSetListRespVO;
import com.qqt.csr.workbench.vo.resp.SkillSetMemberInfoRespVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

@Authorize
@RestController
@RequestMapping("skill-set")
@Tag(name = "技能组管理", description = "技能组管理")
public class SkillSetController {
    @Autowired
    private SkillSetService skillSetService;
    @Autowired
    private SkillSetConfigService skillSetConfigService;
    @Autowired
    private SkillSetMemberService skillSetMemberService;
    @Autowired
    private RedissonLockUtil redissonLockUtil;
    @Autowired
    private CsStatusService csStatusService;

    @PostMapping("/add")
    @Operation(summary = "添加技能组")
    @Log(desc = "添加技能组")
    @Idempotent(model = "skill-set:")
    @OperationLog(level = LogLevel.HIGH, operationMenu = "技能组管理", buttonName = "添加技能组", businessType = BusinessType.INSERT)
    public ObjectResponse<String> addSkillSet(@Validated @RequestBody AddingSkillSetReqVO req) {
        ServiceAssert.notNull(req, StatusCode.Common.NULL_ERROR.getCode(), "请求参数不能为空");
        String tenantId = SessionContextHolder.getHeaderInfo().getTenantId();
        ServiceAssert.isTrue(StringUtils.isNotBlank(tenantId), StatusCode.Common.ILLEGAL.getCode(), "无效的租户");
        Long creatorId = SessionContextHolder.getHeaderInfo().getUserId();
        Long skillSetId = skillSetService.addSkillSet(req, tenantId, creatorId);
        return ObjectResponse.success(skillSetId.toString());
    }

    @PostMapping("/update")
    @Operation(summary = "修改技能组")
    @Log(desc = "修改技能组")
    @Idempotent(model = "skill-set:")
    @OperationLog(level = LogLevel.HIGH, operationMenu = "技能组管理", buttonName = "修改技能组", businessType = BusinessType.UPDATE)
    public ObjectResponse<String> updateSkillSet(@Validated @RequestBody UpdatingSkillSetReqVO req) {
        ServiceAssert.notNull(req, StatusCode.Common.NULL_ERROR.getCode(), "请求参数不能为空");
        String tenantId = SessionContextHolder.getHeaderInfo().getTenantId();
        ServiceAssert.isTrue(StringUtils.isNotBlank(tenantId), StatusCode.Common.ILLEGAL.getCode(), "无效的租户");
        skillSetService.updateSkillSet(req, tenantId);
        return ObjectResponse.success();
    }

    @PostMapping("/move")
    @Operation(summary = "技能组上移下移")
    @Log(desc = "技能组上移下移")
    @Idempotent(model = "skill-set:")
    public ObjectResponse<String> moveSkillSet(@Validated @RequestBody MovingSkillSetReqVO req) {
        ServiceAssert.notNull(req, StatusCode.Common.NULL_ERROR.getCode(), "请求参数不能为空");
        String tenantId = SessionContextHolder.getHeaderInfo().getTenantId();
        ServiceAssert.isTrue(StringUtils.isNotBlank(tenantId), StatusCode.Common.ILLEGAL.getCode(), "无效的租户");
        skillSetService.moveSkillSet(req, tenantId);
        return ObjectResponse.success();
    }

    @PostMapping("/delete")
    @Operation(summary = "删除技能组")
    @Log(desc = "删除技能组")
    @Idempotent(model = "skill-set:")
    @OperationLog(level = LogLevel.HIGH, operationMenu = "技能组管理", buttonName = "删除技能组", businessType = BusinessType.DELETE)
    public ObjectResponse<String> deleteSkillSet(@Validated @RequestBody DeletingSkillSetReqVO req) {
        ServiceAssert.notNull(req, StatusCode.Common.NULL_ERROR.getCode(), "请求参数不能为空");
        String tenantId = SessionContextHolder.getHeaderInfo().getTenantId();
        ServiceAssert.isTrue(StringUtils.isNotBlank(tenantId), StatusCode.Common.ILLEGAL.getCode(), "无效的租户");
        skillSetService.deleteSkillSet(req.getIdList(), tenantId);
        return ObjectResponse.success();
    }

    @IgnoreAuthorize
    @GetMapping("/queryAll")
    @Operation(summary = "查询所有技能组")
    public ObjectResponse<List<SkillSetListRespVO>> queryAllSkillSetList() {
        String tenantId = SessionContextHolder.getHeaderInfo().getTenantId();
        ServiceAssert.isTrue(StringUtils.isNotBlank(tenantId), StatusCode.Common.ILLEGAL.getCode(), "无效的租户");
        List<SkillSet> list = skillSetService.queryAllSkillSetList(tenantId);
        return ObjectResponse.success(list.stream()
                .map(SkillSetListRespVO::of)
                .collect(Collectors.toList()));
    }

    @PostMapping("/config/set")
    @Operation(summary = "设置技能组配置")
    @Log(desc = "设置技能组配置")
    @Idempotent(model = "skill-set:cfg:")
    public ObjectResponse<String> setSkillSetConfig(@Validated @RequestBody SettingSkillSetConfigReqVO req) {
        ServiceAssert.notNull(req, StatusCode.Common.NULL_ERROR.getCode(), "请求参数不能为空");
        String tenantId = SessionContextHolder.getHeaderInfo().getTenantId();
        ServiceAssert.isTrue(StringUtils.isNotBlank(tenantId), StatusCode.Common.ILLEGAL.getCode(), "无效的租户");
        skillSetConfigService.addOrUpdate(req, tenantId);
        return ObjectResponse.success();
    }

    @PostMapping("/config/query")
    @Operation(summary = "查询技能组配置")
    public ObjectResponse<SkillSetConfigInfoRespVO> querySkillSetConfig(@Validated @RequestBody QueryingSkillSetConfigReqVO req) {
        ServiceAssert.notNull(req, StatusCode.Common.NULL_ERROR.getCode(), "请求参数不能为空");
        SkillSetConfig config = skillSetConfigService.queryBySkillSetId(req.getSkillSetId());
        return ObjectResponse.success(SkillSetConfigAssembler.INSTANCE.toSkillSetConfigInfoVo(config));
    }

    @PostMapping("/member/add")
    @Operation(summary = "添加技能组成员")
    @Log(desc = "添加技能组成员")
    @Idempotent(model = "skill-set:m:")
    @OperationLog(level = LogLevel.HIGH, operationMenu = "技能组管理", buttonName = "新增技能组成员", businessType = BusinessType.INSERT)
    public ObjectResponse<String> addMember(@Validated @RequestBody AddingSkillSetMemberReqVO req) {
        ServiceAssert.notNull(req, StatusCode.Common.NULL_ERROR.getCode(), "请求参数不能为空");
        String tenantId = SessionContextHolder.getHeaderInfo().getTenantId();
        ServiceAssert.isTrue(StringUtils.isNotBlank(tenantId), StatusCode.Common.ILLEGAL.getCode(), "无效的租户");
        skillSetMemberService.addSkillSetMember(tenantId, req.getCsIdList(), req.getSkillSetId(), SessionContextHolder.getHeaderInfo().getUserId());
        return ObjectResponse.success();
    }

    @PostMapping("/member/delete")
    @Operation(summary = "删除技能组成员")
    @Log(desc = "删除技能组成员")
    @Idempotent(model = "skill-set:m:")
    @OperationLog(level = LogLevel.HIGH, operationMenu = "技能组管理", buttonName = "删除技能组成员", businessType = BusinessType.DELETE)
    public ObjectResponse<String> deleteMember(@Validated @RequestBody DeletingSkillSetMemberReqVO req) {
        ServiceAssert.notNull(req, StatusCode.Common.NULL_ERROR.getCode(), "请求参数不能为空");
        String tenantId = SessionContextHolder.getHeaderInfo().getTenantId();
        ServiceAssert.isTrue(StringUtils.isNotBlank(tenantId), StatusCode.Common.ILLEGAL.getCode(), "无效的租户");
        skillSetMemberService.deleteBy(tenantId, req.getSkillSetId(), req.getCsIdList());
        csStatusService.removeNotReadyBusyCsId(req.getSkillSetId(), req.getCsIdList());
        return ObjectResponse.success();
    }

    @PostMapping("/member/queryPage")
    @Operation(summary = "查询技能组成员")
    public PageResponse<SkillSetMemberInfoRespVO> queryMemberPage(@Validated @RequestBody PageRequest<QueryingSkillSetMemberReqVO> req) {
        ServiceAssert.notNull(req, StatusCode.Common.NULL_ERROR.getCode(), "请求参数不能为空");
        String tenantId = SessionContextHolder.getHeaderInfo().getTenantId();
        ServiceAssert.isTrue(StringUtils.isNotBlank(tenantId), StatusCode.Common.ILLEGAL.getCode(), "无效的租户");
        return skillSetMemberService.queryPage(req, tenantId);
    }

    @PostMapping("/member/check")
    @Operation(summary = "查询已存在的技能组成员")
    public ObjectResponse<List<Long>> checkMemberList(@Validated @RequestBody QueryingSkillSetMemberReqVO req) {
        ServiceAssert.notNull(req, StatusCode.Common.NULL_ERROR.getCode(), "请求参数不能为空");
        List<Long> existCsIdList = skillSetMemberService.checkMemberList(req.getSkillSetId(), req.getCsIdList());
        return ObjectResponse.success(existCsIdList);
    }
}
